import face_recognition
import argparse, os
import dlib
import matplotlib
import matplotlib.patches as patches
import matplotlib.pyplot as plt

def Draw_Target_Area(know_file_way, unknow_file_way, target_image_data, Per, No):
    target_Area = face_recognition.face_locations(target_image_data)
    im_know = plt.imread(know_file_way)
    im_unknow = plt.imread(unknow_file_way)
    NoNum = No
    for i in range(0, len(Per)):
        plt.figure(NoNum)
        imk = im_know[Per[i][0]:Per[i][2],Per[i][3]:Per[i][1]]
        plt.imshow(imk)
        NoNum += 1
        im = None
    plt.figure(NoNum)
    imunk = im_unknow[target_Area[0][0]:target_Area[0][2],target_Area[0][3]:target_Area[0][1]]
    plt.imshow(imunk)
def Draw_Face_Detector(face, file_way, SN):
    print("---正在建立坐标系")
    height = 0
    length = 0
    img = matplotlib.image.imread(file_way)
    currentAxis = plt.gca()
    plt.figure(SN)
    SN = SN + 1
    plt.imshow(img)
    print("---正在生成坐标\n")
    if len(face) == 0:
        print("---未识别到人脸数据")
    elif len(face) >= 1:
        print("---图中人脸数量为:{}".format(len(face)))
        for i in range(0, len(face)):
            if face[i][2] > face[i][0]:
                height = face[i][2] - face[i][0]
            elif face[i][0] > face[i][2]:
                height = face[i][2] - face[i][0]
            else:
                print("坐标读取错误，无法选中目标区域")

            if face[i][1] > face[i][3]:
                length = face[i][1] - face[i][3]
            elif face[i][1] > face[i][3]:
                length = face[i][1] - face[i][3]
            else:
                print("坐标读取错误，无法选中目标区域")

            y = face[i][0]
            x = face[i][3]
#    print("{}.{}".format(height,length))
            rect = patches.Rectangle((x, y), length, height, linewidth=1, edgecolor='r', facecolor='none')
            currentAxis.add_patch(rect)
    print("---生成坐标完毕\n")
def Draw_Face_Key_Point_Detector(file_way, landmark, model):
    print("---正在检测识别出的人脸关键点")
    if len(landmark) == 0:
        print("---未成功接收识别出的人脸区域")
    elif len(landmark) >= 1:
        print("---成功接收识别的人脸区域")
        for f in range(0, len(landmark)):
            temp = []
            print(landmark[f])
            temp.append(landmark[f])
            print("---构建区域{}的人脸字典".format(f))
            face_landmarks_list = face_recognition.face_landmarks(file_way, temp, model)
            temp.clear()
            k = []
            for key in face_landmarks_list[0].keys():
                k.append(key)
            point_color = (0, 0, 255)
            thickness = 2
            for i in range(0,len(k)):
                for p in face_landmarks_list[0][k[i]]:
                    plt.scatter(p[0], p[1], color='r', s=3)
            face_landmarks_list.clear()
            print("---人脸字典{}构建完成".format(f))
    print("---检测完成")
def Draw_Face_Recognition(unknown_file_way, know_file_data, face_locations, SN, know_file_way):
    print("---加载待检测图片")
    unknown_Image = face_recognition.load_image_file(unknown_file_way)
    unknow_Img = matplotlib.image.imread(unknown_file_way)
    print("---加载完成")

    print("---正在对待检测图片进行编码处理")
    unknown_encoding = face_recognition.face_encodings(unknown_Image)[0]
    print("---完成编码处理")

    print("---正在比对图片编码")
    temp_Error = 0
    designate_Area_No = []
    for i in range(0, len(face_locations)):
        temp_Area = []
        temp_Area.append(face_locations[i])
        temp_encodings = face_recognition.face_encodings(know_file_data, temp_Area)[0]
        results = face_recognition.compare_faces([temp_encodings],unknown_encoding)
        temp_encodings = None
        temp_Area.clear()
        if results[0] == True:
            print("---当前检测的目标人物与识别人物相符")
            designate_Area_No.append(face_locations[i])
            break
        else:
            print("---当前检测的目标人物与识别人物{}不相符".format(i))
            temp_Error += 1

    if temp_Error == len(face_locations):
        print("---已知区域中没有目标人物")
        plt.figure(SN)
        plt.imshow(unknown_Img)
    elif temp_Error <= len(face_locations):
        print("---已知区域中有目标人物")
        print("---检测成功")
        No = SN
        know_path = know_file_way
        unknow_path = unknown_file_way
        Draw_Target_Area(know_path, unknow_path, unknown_Image, designate_Area_No, No)
    else:
        print("---发生未知错误")
def Create_New_SN(SN):
    SN = SN + 1
    return SN
def Certain_RecognizeTarget(unknow_file_way,default_target_way):
    u = unknow_file_way.strip()
    t = default_target_way.strip()
    if u == t:
        print("---没有指定需要识别的目标路径")
        print("---自动选择默认路径为目标进行识别")
    elif u != t:
        try:
            test_open = face_recognition.load_image_file(unknow_file_way)
        except FileNotFoundError as reason:
            print("---当前路径有误，请重新执行并指定正确的目标路径")


parser = argparse.ArgumentParser(description="FaceRecognition")
parser.add_argument('--ReadImage_Way', default="/home/wks/users/zsy/face_recognition/examples/muti-people.jpg", type=str, help='Read Image')
parser.add_argument('--TargetImage_Way', default="/home/wks/users/zsy/face_recognition/examples/xidada.jpg", type=str, help='This Image is Waiting for Recognition')
parser.add_argument('--Face_Location_Model', default="hog", type=str, help='Use hog or CNN for face locations')
parser.add_argument('--Face_Landmark_Model', default="large", type=str, help='Use a large or small model for save face key points,large model include 64-68 points,but small model just include 5 points')
parser.add_argument('--Up_Sample', default=1, type=int, help='How many times to upsample the image looking for faces. Higher numbers find smaller faces.')
opt = parser.parse_args()

if __name__=="__main__":
    print("---加载已知图片")
    image = face_recognition.load_image_file(opt.ReadImage_Way)
    print("---加载完成")

    print("---定位图片中的人脸")
    face_locations = face_recognition.face_locations(image, opt.Up_Sample, opt.Face_Location_Model)
    print("---定位完成---")

    print("---正在生成效果图序列")
    Serial_Number = 1
    print("---生成完毕")


    print("---正在生成检测效果图")
    Draw_Face_Detector(face_locations, opt.ReadImage_Way, Serial_Number)
    Serial_Number = Create_New_SN(Serial_Number)

    Draw_Face_Key_Point_Detector(image, face_locations, opt.Face_Landmark_model)
    print("---检测效果呈现完毕")

    print("---正在确认是否有目标人脸需要识别")
    T = parser.get_default("TargetImage_Way")
    Certain_RecognizeTarget(opt.TargetImage_Way, T)
    Draw_Face_Recognition(opt.TargetImage_Way, image, face_locations, Serial_Number, opt.ReadImage_Way)
    Serial_Number = Create_New_SN(Serial_Number)

    print("---目标识别完毕")

    plt.show()



